package com.bruce.tool.web.filter.core;

import com.bruce.tool.common.exception.BaseRuntimeException;
import com.bruce.tool.common.util.SpringBeanUtils;
import com.bruce.tool.common.util.trace.TraceNoUtils;
import com.bruce.tool.web.filter.annotation.ForbidResubmit;
import com.bruce.tool.web.filter.handler.LockHandler;
import com.bruce.tool.web.filter.util.RequestUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**防重复提交**/
@Slf4j
@SuppressWarnings("all")
public class ResubmitHandlerInterceptor implements HandlerInterceptor {

    private final String prefix = "resubmit";

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        HandlerMethod method = (HandlerMethod) handler;
        ForbidResubmit forbidResubmit = method.getMethodAnnotation(ForbidResubmit.class);
        if (forbidResubmit == null) {
            return true;
        }

        String token = RequestUtils.fetchToken(request);
        if (StringUtils.isBlank(token)) {
            throw new BaseRuntimeException("ResubmitNotSupport", "重复请求校验,只支持get,postjson,postform");
        }
        token = this.prefix + token;
        // 分布式锁
        LockHandler lockHandler = SpringBeanUtils.getBean(LockHandler.class);
        if (null == lockHandler) {
            throw new BaseRuntimeException("ResubmitNotInit", "分布式锁未初始化,无法开启重复请求校验");
        }
        if (!lockHandler.lock(token, TraceNoUtils.fetchTraceNo(), forbidResubmit.value())) {
            throw new BaseRuntimeException("ResubmitError", "重复请求触发限制,请不要重复提交数据");
        }
        return true;
    }

}